package com.xyht.sca_s.student_manage_system.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xyht.sca_s.student_manage_system.auth.entity.AuthResourceResp;
import com.xyht.sca_s.student_manage_system.auth.entity.PermissionEntity;
import com.xyht.sca_s.student_manage_system.auth.service.AuthService;
import com.xyht.sca_s.student_manage_system.auth.util.JwtTokenUtil;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsApplication;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsResource;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsRoleApplicationRelation;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsRoleResourceRelation;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsApplicationMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsResourceMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsRoleApplicationRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsRoleResourceRelationMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;

import static com.xyht.sca_s.student_manage_system.auth.constant.CommonConstant.CLIENT_HEADER;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.AppUpDownConstant.APP_UP;

@Service
public class AuthServiceImpl implements AuthService {
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private CacheUtil cacheUtil;
    @Resource
    private SmsRoleApplicationRelationMapper smsRoleApplicationRelationMapper;
    @Resource
    private SmsRoleResourceRelationMapper smsRoleResourceRelationMapper;
    @Resource
    private SmsApplicationMapper smsApplicationMapper;
    @Resource
    private SmsResourceMapper smsResourceMapper;

    @Override
    public ResponseResult isAppPermission(String requestPath, HttpServletRequest request) {
        if (isNullOrEmpty(requestPath)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        PermissionEntity permissionEntity = new PermissionEntity();
        String user_id = jwtTokenUtil.getUserIdByRequest(request);
        String client = request.getHeader(CLIENT_HEADER);

        List<String> roleList = cacheUtil.getRoleList(user_id);
        if (roleList.size() < 1) {
            permissionEntity.setIsPermission(false);
            return CommonResult.success(permissionEntity);
        }

        List<SmsRoleApplicationRelation> roleApplicationRelationList = smsRoleApplicationRelationMapper.selectList(
                new QueryWrapper<SmsRoleApplicationRelation>()
                        .lambda().select(SmsRoleApplicationRelation::getAppId)
                        .in(SmsRoleApplicationRelation::getRoleId, roleList)
                        .eq(SmsRoleApplicationRelation::getClientFlag, client)
                        .groupBy(SmsRoleApplicationRelation::getAppId));
        List<String> appList = roleApplicationRelationList.stream().map(SmsRoleApplicationRelation::getAppId).collect(Collectors.toList());
        if (appList.size() < 1) {
            permissionEntity.setIsPermission(false);
            return CommonResult.success(permissionEntity);
        }

        QueryWrapper<SmsApplication> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(SmsApplication::getId, appList)
                .eq(SmsApplication::getAppClient, client)
                .eq(SmsApplication::getAppPath, requestPath)
                .eq(SmsApplication::getUpDown, APP_UP);
        List<SmsApplication> smsApplicationList = smsApplicationMapper.selectList(queryWrapper);
        if (smsApplicationList.size() < 1) {
            permissionEntity.setIsPermission(false);
            return CommonResult.success(permissionEntity);
        }

        SmsApplication newApp = smsApplicationList.get(0);

        List<SmsRoleResourceRelation> roleResourceRelationList = smsRoleResourceRelationMapper.selectList(
                new QueryWrapper<SmsRoleResourceRelation>()
                        .lambda().select(SmsRoleResourceRelation::getResourceId)
                        .in(SmsRoleResourceRelation::getRoleId,roleList)
                        .eq(SmsRoleResourceRelation::getAppId, newApp.getId())
                        .eq(SmsRoleResourceRelation::getClientFlag, client)
                        .groupBy(SmsRoleResourceRelation::getResourceId));
        List<String> resourceList = roleResourceRelationList.stream().map(SmsRoleResourceRelation::getResourceId).collect(Collectors.toList());
        List<AuthResourceResp> resourceRespList = new ArrayList<>();
        if (resourceList.size() > 0) {
            List<SmsResource> smsResourceList = smsResourceMapper.selectList(new QueryWrapper<SmsResource>()
                    .lambda().in(SmsResource::getId, resourceList));
            resourceRespList = smsResourceList.stream().map(res -> {
                AuthResourceResp resourceResp = new AuthResourceResp();
                BeanUtils.copyProperties(res, resourceResp);
                return resourceResp;
            }).collect(Collectors.toList());
        }
        permissionEntity.setResourceRespList(resourceRespList);
        permissionEntity.setIsPermission(true);
        return CommonResult.success(permissionEntity);
    }

    @Override
    public ResponseResult isDynamicAppPermission(String newAppId, HttpServletRequest request) {
        if (isNullOrEmpty(newAppId)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<SmsApplication> newApplicationList = smsApplicationMapper.selectList(new LambdaQueryWrapper<SmsApplication>()
                .eq(SmsApplication::getNewAppId, newAppId));
        if (newApplicationList == null || newApplicationList.size()<1){
            return CommonResult.failed(CommonCodeEnum.INVALID_REQUEST);
        }
        String app_type = newApplicationList.get(0).getAppType();

        PermissionEntity permissionEntity = new PermissionEntity();
        String user_id = jwtTokenUtil.getUserIdByRequest(request);
        String client = request.getHeader(CLIENT_HEADER);

        List<String> roleList = cacheUtil.getRoleList(user_id);
        if (roleList.size() < 1) {
            permissionEntity.setIsPermission(false);
            return CommonResult.success(permissionEntity);
        }

        List<SmsRoleApplicationRelation> roleApplicationRelationList = smsRoleApplicationRelationMapper.selectList(
                new QueryWrapper<SmsRoleApplicationRelation>()
                        .lambda().select(SmsRoleApplicationRelation::getAppId)
                        .in(SmsRoleApplicationRelation::getRoleId, roleList)
                        .eq(SmsRoleApplicationRelation::getClientFlag, client)
                        .groupBy(SmsRoleApplicationRelation::getAppId));
        List<String> appList = roleApplicationRelationList.stream().map(SmsRoleApplicationRelation::getAppId).collect(Collectors.toList());
        if (appList.size() < 1) {
            permissionEntity.setIsPermission(false);
            return CommonResult.success(permissionEntity);
        }

        QueryWrapper<SmsApplication> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(SmsApplication::getId, appList)
                .eq(SmsApplication::getAppClient, client)
                .eq(SmsApplication::getAppType, app_type)
                .eq(SmsApplication::getUpDown, APP_UP);
        List<SmsApplication> smsApplicationList = smsApplicationMapper.selectList(queryWrapper);
        if (smsApplicationList.size() < 1) {
            permissionEntity.setIsPermission(false);
            return CommonResult.success(permissionEntity);
        }

        SmsApplication newApp = smsApplicationList.get(0);

        List<SmsRoleResourceRelation> roleResourceRelationList = smsRoleResourceRelationMapper.selectList(
                new QueryWrapper<SmsRoleResourceRelation>()
                        .lambda().select(SmsRoleResourceRelation::getResourceId)
                        .in(SmsRoleResourceRelation::getRoleId,roleList)
                        .eq(SmsRoleResourceRelation::getAppId, newApp.getId())
                        .eq(SmsRoleResourceRelation::getClientFlag, client)
                        .groupBy(SmsRoleResourceRelation::getResourceId));
        List<String> resourceList = roleResourceRelationList.stream().map(SmsRoleResourceRelation::getResourceId).collect(Collectors.toList());
        List<AuthResourceResp> resourceRespList = new ArrayList<>();
        if (resourceList.size() > 0) {
            List<SmsResource> smsResourceList = smsResourceMapper.selectList(new QueryWrapper<SmsResource>()
                    .lambda().in(SmsResource::getId, resourceList));
            resourceRespList = smsResourceList.stream().map(res -> {
                AuthResourceResp resourceResp = new AuthResourceResp();
                BeanUtils.copyProperties(res, resourceResp);
                return resourceResp;
            }).collect(Collectors.toList());
        }
        permissionEntity.setResourceRespList(resourceRespList);
        permissionEntity.setIsPermission(true);
        return CommonResult.success(permissionEntity);
    }
}
